package com.zrt.dao.impl;

import com.zrt.dao.DetailParseDao;
import com.zrt.domain.Reference;
import com.zrt.util.NamePart;
import com.zrt.util.OriginPart;
import com.zrt.util.TimePart;
import org.springframework.stereotype.Repository;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Repository
public class DetailParseDaoImpl implements DetailParseDao {

    boolean flag = false;
   // List<String> referencesList = new ArrayList<>();

    public void JudgeTheFormatOfNum(String UndividedReferences,List<String> referencesList) {
        flag = false;
        String startOfUR = UndividedReferences.substring(0, 5);


        Pattern pattern1 = Pattern.compile("\\[\\d+\\]");
        Pattern pattern2 = Pattern.compile("\\d\\.");
        Matcher m1 = pattern1.matcher(startOfUR);
        Matcher m2 = pattern2.matcher(startOfUR);
        if (m1.find()) {
            FindTheBeginning1(UndividedReferences.replaceAll("(\\r\\n|\\n|\\\\n|)", ""),referencesList);
        } else {

            JudgeTheFormatOfEnd(UndividedReferences);
        }
    }




    public void FindTheBeginning1(String UndividedReferences, List<String> referenceList) {

        int start = 0;
        int end = 0;
        String pattern = "\\[\\d+\\]";

        Pattern p1 = Pattern.compile(pattern);


        Matcher m = p1.matcher(UndividedReferences);
        int count = 0;

        while (m.find()) {
            count++;
            start = end;
            end = m.start();
            SplitReferences(UndividedReferences, start, end, referenceList);

        }
        String stringIncludingOnlyTheLastReference = UndividedReferences.substring(end);
        start = 0;
        end = 0;

        Pattern patternYear = Pattern.compile("(20|19)\\d{2}");

        Matcher mYear = patternYear.matcher(stringIncludingOnlyTheLastReference);

        while (mYear.find()) {

            end = mYear.end();

            SplitReferences(stringIncludingOnlyTheLastReference, start, end,referenceList);
            break;
        }
    }

    public void FindTheBeginning2(String UndividedReferences,List<String> referenceList) {

        int start = 0;
        int end = 0;
        String pattern2 = "\\d+\\.";

        Pattern p2 = Pattern.compile(pattern2);

        Matcher m = p2.matcher(UndividedReferences);
        int count = 0;

        while (m.find()) {

            count++;

            start = end;
            end = m.start();

            SplitReferences(UndividedReferences, start, end,referenceList);
        }
    }

    public void JudgeTheFormatOfEnd(String UndividedReferences) {
        String startOfUR = UndividedReferences.substring(0, 400);


        Pattern pattern1 = Pattern.compile("\\((20|19)\\d{2}\\)");
        Pattern pattern2 = Pattern.compile("(20|19)\\d{2}\\.");
        Pattern pattern3 = Pattern.compile("(20|19)\\d{2}");
        Matcher m1 = pattern1.matcher(startOfUR);
        Matcher m2 = pattern2.matcher(startOfUR);
        if (m1.find()) {
            FindTheEnd(UndividedReferences.replaceAll("(\\r\\n|\\n|\\\\n|)", ""), pattern1);
        } else if (m2.find()) {

            FindTheEnd(UndividedReferences.replaceAll("(\\r\\n|\\n|\\\\n|)", ""), pattern2);
        } else {
            FindTheEnd(UndividedReferences.replaceAll("(\\r\\n|\\n|\\\\n|)", ""), pattern3);
        }
    }

    @Override
    public void FindTheEnd(String UndividedReferences, Pattern pattern) {

    }

    public void FindTheEnd(String UndividedReferences, Pattern pattern,List<String> referenceList) {

        int start = 0;
        int end = 0;

        Matcher m = pattern.matcher(UndividedReferences);


        int count = 0;
        while (m.find()) {
            count++;


            start = end;
            end = m.end();


            SplitReferences(UndividedReferences, start, end,referenceList);
            if (flag) {
                break;

            }
        }

    }


    public void SplitReferences(String UndividedReferences, int start, int end , List<String> referencesList) {

        if (end != 0) {

            String reference = UndividedReferences.substring(start, end);
            JudgeWhetherTheReferenceHasEnded(reference);
            if (flag == false) {


                referencesList.add(reference);
            }
        }


    }

    public void JudgeWhetherTheReferenceHasEnded(String reference) {
        Pattern pattern = Pattern.compile("A\\s[A-Z]{2,}");
        Matcher m = pattern.matcher(reference);
        if (m.find()) {
            flag = true;

        }
    }

    public List<String> RemoveElementsThatAreTooShort(List<String> referencesList) {
        for (int i = 0; i < referencesList.size(); i++) {
            if (referencesList.get(i).length() < 40)
                referencesList.remove(i);

        }
        return referencesList;
    }

    public NamePart JudgeNameFormat(String Reference) {
        NamePart namePart = new NamePart();
        String[] strings = new String[10];
        int count = 0;

        int end = 0;

        Pattern pattern3 = Pattern.compile("([A-Z]\\.\\s[A-Z][a-z]+)|((?:[A-Z][a-z]+\\-)?[A-Z][a-z]+\\s(?:[A-Z]\\s)?[A-Z][a-z]+)");

        Matcher m3 = pattern3.matcher(Reference);



        while (m3.find()) {
            if (m3.start() - end < 8) {
                strings[count] = m3.group(0);

                count++;
            } else {
                break;
            }
            end = m3.end();
        }

        namePart.setName(strings);
        namePart.setEnd(end);
        return namePart;
    }


    public OriginPart SearchOrigin(String reference) {
        OriginPart originPart = new OriginPart();

        int start = 0;

        Pattern pattern = Pattern.compile("In ECCV|In CVPR|IEEE TPAMI|In NeurIPS|TNNLS|In ICML|ICML|arXiv");
        Matcher m1 = pattern.matcher(reference);
        while (m1.find()) {
            String Origin = reference.substring(m1.start(), m1.end());
            originPart.setOrigin(Origin);
            // System.out.println(Origin);
            start = m1.start();
        }
        originPart.setStart(start);
        return originPart;

    }

    public void SearchResult(String reference, Matcher NameM, Matcher OriginM) {
        String Result = reference.substring(NameM.end(), OriginM.start());
        System.out.println(Result);
    }

    public TimePart SearchTime(String reference) {
        TimePart timePart = new TimePart();
        int start = 0;

        Pattern pattern = Pattern.compile("((20|19)\\d{2})|((20|19)\\d{2}\\.)|(\\((20|19)\\d{2}\\))");
        Matcher m1 = pattern.matcher(reference);
        while (m1.find()) {
            String Time = reference.substring(m1.start(), m1.end());
            //System.out.println(Time);
            timePart.setTime(Time);
            start = m1.start();
        }
        timePart.setStart(start);
        return timePart;
    }

    public List<Reference> TraverseAndSplit(List<String> Referemces) {
        List<Reference> referenceList = new ArrayList<>();
        for (int i = 0; i < Referemces.size(); i++) {
            //Reference reference = new Reference();

            String Result = null;
            NamePart namePart = JudgeNameFormat(Referemces.get(i));
            OriginPart originPart = SearchOrigin(Referemces.get(i));
            TimePart timePart = SearchTime(Referemces.get(i));
            if (originPart.getStart() != 0) {
                Result = Referemces.get(i).substring(namePart.getEnd(), originPart.getStart());

            } else if (timePart.getStart() != 0) {
                Result = Referemces.get(i).substring(namePart.getEnd(), timePart.getStart());

            }

            String[] name = namePart.getName();
            String s = testArrayTransformedToString3(name);

            Reference reference = new Reference(i, s, Result,originPart.getOrigin(),timePart.getTime());

            referenceList.add(reference);

        }
        return referenceList;

    }

    public List<Reference> TraverseAndSplitTest(List<String> Referemces) {
        List<Reference> referenceList = new ArrayList<>();
        for (int i = 0; i < Referemces.size(); i++) {
            //Reference reference = new Reference();

            String Result = null;
            NamePart namePart = JudgeNameFormat(Referemces.get(i));
            OriginPart originPart = SearchOrigin(Referemces.get(i));
            TimePart timePart = SearchTime(Referemces.get(i));
            if (originPart.getStart() != 0) {
                Result = Referemces.get(i).substring(namePart.getEnd(), originPart.getStart());

            } else if (timePart.getStart() != 0) {
                Result = Referemces.get(i).substring(namePart.getEnd(), timePart.getStart());

            }
            String[] name = namePart.getName();
            String s = testArrayTransformedToString3(name);
            Reference reference = new Reference(0, s, Result,originPart.getOrigin(),timePart.getTime());

            referenceList.add(reference);

        }
        return referenceList;

    }

    public String testArrayTransformedToString3(String[] name){
        int k = 0;
        StringBuffer sb = new StringBuffer();
        for (int i = 0 ; i < name.length ; i++){
            if (name[i]!=null){
                k++;
            }
        }
        for (int i = 0 ; i < k ; i++){
            if (i<k-1){
                sb.append(name[i]).append(",");
            }else {
                sb.append(name[i]);
            }
        }
        return sb.toString();
    }

}
